// 目的是达到无痛刷新token
// 定义一个全局变量，判断是否在刷新toke,如果当前没有在刷新token，就为false
let isrefresh = false
// 保存正在刷新token过程中，用户发起的请求
let retryRequest = []

// 请求拦截器，用于将token放置在请求体中，一般放在请求头中
// axios1是axios创建的实例
const axios1 = axios.create()
// 请求拦截器：interceptors.request.use接收一个函数作为参数
// 而这个函数，接收一个形参，就是请求的配置对象
axios1.interceptors.request.use(
    async function(config){

        // 如果仓库中存在token，就发请求的时候带上这个token
        if(!config.headers.Authorization && store.state.user && store.state.user.token){
            // 把token加在请求头中
            config.headers.Authorization = 'Bearer '+ store.state.user.token

        }
        return config
    }
)

// 响应拦截器，实现无痛刷新token
//响应拦截器接收的参数接收两个函数作为参数，第一个参数是响应成功的时候执行，第二个则是响应失败的的时候执行

axios1.interceptors.response.use(
    // 成功的时候执行
    async function(response){
        // 首先拿到响应的内容
        const res = response.data;
        // 判断响应的状态码
        if(res.errcode == 0){
            // 符合接口文档成功的状态，直接返回出去
            return Promise.resolve(res)
        }else if(res.errcode == 30001 || res.errcode == 40001 || res.errcode== 50001) {
            // 如果不是成功，就再次判断状态码是不是token过期
            //判断的状态码是由后端给的接口文档所定义的，若为上方的状态码，则执行token刷新
            // 首先拿到本次请求的配置对象
            let config = response.config
            //判断，如果当前是登录页面，就不需要做刷新token的操作,不是登录页面才需要
            if(Router.currentRoute.path != "/login"){
                // 如果此时没有在刷新token，就进行刷新
                if(!isrefresh){
                    // isrefresh默认为false，就没有在刷新token，此时就需要进行刷新，改为true
                    isrefresh = true
                    // 进行刷新token操作,调用通过refresh获取token的接口
                    return store.dispatch("user/refreshToken")
                    .then(res=>{
                        // 拿到成功后的token,重新给到请求头中
                        config.headers.Authorization = 'Bearer '+ res.Token
                        // 遍历在token刷新期间，搁置的请求，并重新发起
                        retryRequest.forEach(item=> item(res))
                        // 遍历完成以后将数组清空
                        retryRequest= []
                        // 并且再次发送本次请求
                        return axios1.request(config)
                    })
                    .catch(()=>{
                        // 如果在重新获取的过程中，获取新的token失败，就定位到登录组件
                        //并且清空请求队列
                        retryRequest=[]
                        //提示消息
                        message.error("自动登录失败，请重新登录")
                        // 清空仓库中的用户信息
                        stroe.dispatch("user/logout")
                        // 跳转到登录页
                        Router.replace({path:"/login",query:{}})
                    })
                    .finally(()=>{
                        // 无论是失败还是成功，都重置flag
                        isrefresh= false
                    })
                }else{
                    // 如果此时正在刷新token
                    // 正在刷新token，返回一个未执行resolve的promise
                    // 把promise 的resolve 保存到队列的回调里面，等待刷新Token后调用
                    // 原调用者会处于等待状态直到 队列重新发起请求，再把响应返回，以达到用户无感知的目的（无痛刷新）
                    return new Promise(resolve => {
                        // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
                        retryRequests.push(info => {
                            // 将新的Token重新赋值
                        config.params.token = info.Token;
                        config.params.appkey = info.AppKey;
                        resolve(Instance.request(config));
                        });
                    });
                }
            }

        }else{
            // 如果都不是，则直接将错误返回
            return Promise.reject(res)
        }
    },
    // 失败的时候执行
    function(error){
        // 定义一个错误对象
        let err = {};
        // 如果返回的错误对象有响应体，就将响应体的内容取到新对象
        if(error.response){
            err.errcode= error.response.status;
            err.errmsg = error.response.statusText;
        }else{
        // 如果没有错误的响应体就返回错误消息
            err.errcode=-1;
            err.errmsg = error.message;
        }
        // 将错误对象返回
        return Promise.reject(err);
    }
)